package com.mangofactory.flapper.parsley
{
	import com.mangofactory.aop.SimpleCalculator;
	import com.mangofactory.aop.StubAspect;
	import com.mangofactory.aop.configuration.AspectContainerBuilder;
	import com.mangofactory.aop.configuration.MetatagProxyPolicy;
	import com.mangofactory.aop.configuration.tag.MetatagAspectDefinition;
	import com.mangofactory.flapper.parsley.lifecycle.ProxyGeneratorConfigurationProcessor;
	
	import flash.events.Event;
	
	import mx.core.FlexGlobals;
	
	import org.as3commons.bytecode.proxy.IProxyFactory;
	import org.as3commons.bytecode.proxy.ProxyFactory;
	import org.as3commons.bytecode.reflect.ByteCodeType;
	import org.flexunit.asserts.assertEquals;
	import org.flexunit.asserts.assertNotNull;
	import org.flexunit.asserts.assertTrue;
	import org.flexunit.async.Async;
	import org.mockito.integrations.flexunit4.MockitoClassRunner;
	import org.spicefactory.parsley.core.context.Context;
	import org.spicefactory.parsley.dsl.context.ContextBuilder;
	
	public class ContextSupportTests
	{
		private var runner:MockitoClassRunner;
		private var proxyFactory:IProxyFactory;
		
		[BeforeClass]
		public static function setupClass():void
		{
			ByteCodeType.fromLoader(FlexGlobals.topLevelApplication.loaderInfo);
		}
		
		[Before]
		public function setup():void
		{
			proxyFactory = new ProxyFactory();
		}
		[Test(async)]
		public function requestingLoggerAnnotatedClassGetsProxy():void
		{
			var metatagRegistry:MetatagProxyPolicy = new MetatagProxyPolicy();
			var aspect:StubAspect = new StubAspect();
			var aspectContainerBuilder:AspectContainerBuilder = new AspectContainerBuilder();
			aspectContainerBuilder.addMetatagAspect(new MetatagAspectDefinition("Log",aspect));
			
			var proxyProcessor:ProxyGeneratorConfigurationProcessor = new ProxyGeneratorConfigurationProcessor(aspectContainerBuilder);
			var builder:ContextBuilder = ContextBuilder
				.newSetup()
				.newBuilder()
				.config(proxyProcessor)
			
			
			builder.objectDefinition().forClass(SimpleCalculator).asSingleton().register();
			
			var context:Context = builder.build();
			var asyncHandler:Function = Async.asyncHandler(this,onSetupComplete,500,[context,aspect]);
			proxyProcessor.addEventListener(Event.COMPLETE,asyncHandler,false,int.MIN_VALUE);
		}
		
		private function onSetupComplete(event:Event,params:Array):void
		{
			var context:Context = params[0];
			var aspect:StubAspect = params[1];
			var logger:SimpleCalculator = context.getObjectByType(SimpleCalculator) as SimpleCalculator;
			var result:int = logger.add(2,3);
			
			assertNotNull(logger);
			assertTrue(logger.wasCalled);
			assertTrue(aspect.wasCalled);
			assertEquals(5,result);
		}
	}
}
